#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "MyString.h"
#include "DynamicArray.h"
#define Map_Size 6
#define true 1
#define false 0
struct Player
{
    int HP;
    int attack;
    int x;
    int y;
    int pocket;
};

struct Monster
{
    MyString name;
    int HP;
    int attack;
    int x;
    int y;
};

struct LuckyWheel
{
    MyString name;
    int HP;
    int AP;
    int Value;
};

struct Treasure
{
    MyString name;
    int ap;
    int blood;
    int x;
    int y;
};

struct Coin
{
    MyString name;
    int value;
    int x;
    int y;
};

void InitPlayer(struct Player *player)
{
    player->HP = 100;
    player->attack = 15;
    player->x = 0;
    player->y = 0;
    player->pocket = 0;
}

int GetRandNumber(int max)
{
    return rand() % max;
}

struct Monster *CreateMonster(const char *name, int HP, int attack)
{
    struct Monster *monster = (struct Monster *)malloc(sizeof(struct Monster));
    if (monster == NULL)
    {
        printf("Create Monster Error!\n");
        return NULL;
    }
    monster->HP = HP;
    monster->attack = attack;
    Initiallize(&monster->name, name);

    monster->x = GetRandNumber(Map_Size);
    monster->y = GetRandNumber(Map_Size);
    while (monster->x == 0 && monster->y == 0)
    {
        monster->x = GetRandNumber(Map_Size);
        monster->y = GetRandNumber(Map_Size);
    }

    return monster;
}

struct Treasure *CreateTreasure(const char *name, int blood, int ap)
{
    struct Treasure *treasure = (struct Treasure *)malloc(sizeof(struct Treasure));
    if (treasure == NULL)
    {
        printf("Create Treasure Error!\n");
        return NULL;
    }
    treasure->blood = blood;
    treasure->ap = ap;
    Initiallize(&treasure->name, name);

    treasure->x = GetRandNumber(Map_Size);
    treasure->y = GetRandNumber(Map_Size);
    while (treasure->x == 0 && treasure->y == 0)
    {
        treasure->x = GetRandNumber(Map_Size);
        treasure->y = GetRandNumber(Map_Size);
    }

    return treasure;
}

struct Coin *CreateCoin(const char *name, int value)
{
    struct Coin *coin = (struct Coin *)malloc(sizeof(struct Coin));
    if (coin == NULL)
    {
        printf("Create Coin Error!\n");
        return NULL;
    }
    coin->value = value;
    Initiallize(&coin->name, name);

    coin->x = GetRandNumber(Map_Size);
    coin->y = GetRandNumber(Map_Size);
    while (coin->x == 0 && coin->y == 0)
    {
        coin->x = GetRandNumber(Map_Size);
        coin->y = GetRandNumber(Map_Size);
    }

    return coin;
}

struct LuckyWheel *CreateLWheel(const char *name, int HP, int AP, int Value)
{
    struct LuckyWheel *LWheel = (struct LuckyWheel *)malloc(sizeof(struct LuckyWheel));
    if (LWheel == NULL)
    {
        printf("Create LuckyWheel Error!\n");
        return NULL;
    }
    LWheel->AP = AP;
    LWheel->HP = HP;
    LWheel->Value = Value;
    Initiallize(&LWheel->name, name);

    return LWheel;
}

void InitMonsters(struct DynamicArray *array)
{
    if (ArrayInit(array) == false)
    {
        return;
    }

    InsertArray(array, CreateMonster("IKUN", 300, 30));
    InsertArray(array, CreateMonster("PIG", 60, 15));
    InsertArray(array, CreateMonster("PIG", 60, 15));
    InsertArray(array, CreateMonster("PIG", 60, 15));
    InsertArray(array, CreateMonster("MOUSE", 20, 5));
    InsertArray(array, CreateMonster("MOUSE", 20, 5));
    InsertArray(array, CreateMonster("MOUSE", 20, 5));
    InsertArray(array, CreateMonster("MOUSE", 20, 5));
    InsertArray(array, CreateMonster("MOUSE", 20, 5));
}

void InitTreasure(struct DynamicArray *array)
{
    if (ArrayInit(array) == false)
    {
        return;
    }

    InsertArray(array, CreateTreasure("宝藏", 30, 15));
    InsertArray(array, CreateTreasure("珍珠", 20, 8));
    InsertArray(array, CreateTreasure("珍珠", 20, 8));
    InsertArray(array, CreateTreasure("珍珠", 20, 8));
    InsertArray(array, CreateTreasure("药水", 10, 4));
    InsertArray(array, CreateTreasure("药水", 10, 4));
    InsertArray(array, CreateTreasure("药水", 10, 4));
    InsertArray(array, CreateTreasure("药水", 10, 4));
    InsertArray(array, CreateTreasure("药水", 10, 4));
}

void InitLuckyWheel(struct DynamicArray *array)
{
    if (ArrayInit(array) == false)  
    {
        return;
    }

    InsertArray(array, CreateLWheel("宝藏", 30, 15,0));
    InsertArray(array, CreateLWheel("宝藏", 30, 15,0));
    InsertArray(array, CreateLWheel("宝藏", 30, 15,0));
    InsertArray(array, CreateLWheel("宝藏", 30, 15,0));
    InsertArray(array, CreateLWheel("宝藏", 30, 15,0));
    InsertArray(array, CreateLWheel("宝藏", 30, 15,0));
    InsertArray(array, CreateLWheel("宝藏", 30, 15,0));
    InsertArray(array, CreateLWheel("宝藏", 30, 15,0));
    InsertArray(array, CreateLWheel("宝藏", 30, 15,0));

}

void InitCoin(struct DynamicArray *array)
{
    if (ArrayInit(array) == false)
    {
        return;
    }

    InsertArray(array, CreateCoin("金币", 5));
    InsertArray(array, CreateCoin("金币", 5));
    InsertArray(array, CreateCoin("银币", 3));
    InsertArray(array, CreateCoin("银币", 3));
    InsertArray(array, CreateCoin("银币", 3));
    InsertArray(array, CreateCoin("铜币", 1));
    InsertArray(array, CreateCoin("铜币", 1));
    InsertArray(array, CreateCoin("铜币", 1));
    InsertArray(array, CreateCoin("铜币", 1));
    InsertArray(array, CreateCoin("铜币", 1));
    InsertArray(array, CreateCoin("老阴币", -2));
    InsertArray(array, CreateCoin("老阴币", -2));
}

void MakeMove(struct Player *player, char symbol)
{
    switch (symbol)
    {
    case 'w':
        player->x--;
        break;
    case 's':
        player->x++;
        break;
    case 'a':
        player->y--;
        break;
    case 'd':
        player->y++;
        break;
        // case 'o': store(int gold)

    default:
        break;
    }

    if (player->x < 0)
        player->x = 0;
    if (player->x >= Map_Size)
        player->x = Map_Size - 1;
    if (player->y < 0)
        player->y = 0;
    if (player->y >= Map_Size)
        player->y = Map_Size - 1;
}

int Battle(struct Player *player, struct Monster *monster)
{
    system("clear");
    printf("                您遭遇了|%s|血量:|%d|  攻击力:|%d|\n", monster->name.string, monster->HP, monster->attack);
    printf("                你当前血量|%d|攻击力|%d| \n", player->HP, player->attack);
    printf("***************************************************************************************************\n");
    printf("*                                              开始战斗！                                           *\n");
    printf("***************************************************************************************************\n");
    while (player->HP > 0 && monster->HP > 0)
    {
        printf("请选择您要执行的行为: \n");
        printf("1、普通攻击\n");
        printf("2、暴击\n");
        printf("3、逃跑\n");
        int choice;
        scanf("%d", &choice);
        getchar();
        switch (choice)
        {
        case 1:
            player->HP -= monster->attack;
            monster->HP -= player->attack;
            printf("                |%s|对你造成了%d伤害\n", monster->name.string, monster->attack);
            printf("                你对|%s|造成了%d伤害\n", monster->name.string, player->attack);
            printf("                你当前血量|%d|攻击力|%d| \n", player->HP, player->attack);
            printf("                |%s|当前血量|%d|攻击力|%d| \n", monster->name.string, monster->HP, monster->attack);
            printf("                你当前所在的位置是<%d , %d>\n ", player->x, player->y);
            break;

        case 2:
            if (GetRandNumber(2) == 1)
            {
                printf("                |%s|对你造成了%d伤害\n", monster->name.string, monster->attack);
                printf("                你对|%s|造成了%d伤害\n", monster->name.string, player->attack * 2);
                player->HP -= monster->attack;
                player->HP -= monster->attack * 2;
                printf("                你当前血量|%d|攻击力|%d| \n", player->HP, player->attack);
                printf("                |%s|当前血量|%d|攻击力|%d| \n", monster->name.string, monster->HP, monster->attack);
                printf("                你当前所在的位置是<%d , %d>\n ", player->x, player->y);
            }
            else
            {
                printf("                |%s|对你造成了%d伤害\n", monster->name.string, monster->attack);
                printf("                暴击失败!无法发动攻击!\n");
                player->HP -= monster->attack;
                printf("                你当前血量|%d|攻击力|%d| \n", player->HP, player->attack);
                printf("                |%s|当前血量|%d|攻击力|%d| \n", monster->name.string, monster->HP, monster->attack);
                printf("                你当前所在的位置是<%d , %d>\n ", player->x, player->y);
            }
            break;

        case 3:
            if (GetRandNumber(2) == 1)
            {
                printf("                逃跑成功            \n");
                printf("\n");
                switch (GetRandNumber(4))
                {
                case 0:
                    player->x++;
                    printf("                跑得这么快，你是参加奥运会了吗？\n");
                    break;
                case 1:
                    player->x--;
                    printf("                是逃跑还是在进行突击训练?\n");
                    break;
                case 2:
                    player->y++;
                    printf("                看来你的腿比你的勇气更强壮。\n");
                    break;
                case 3:
                    player->y--;
                    printf("                逃跑是你唯一擅长的技能吗？\n");
                    break;
                }
                if (player->x < 0)
                    player->x = 0;
                if (player->x >= Map_Size)
                    player->x = Map_Size - 1;
                if (player->y < 0)
                    player->y = 0;
                if (player->y >= Map_Size)
                    player->y = Map_Size - 1;
                printf("                你当前血量|%d|攻击力|%d| \n", player->HP, player->attack);
                printf("                你当前所在的位置是<%d , %d>\n", player->x, player->y);
                return true;
            }
            else
            {
                printf("逃跑失败!\n");
                printf("                |%s|对你造成了%d伤害\n", monster->name.string, monster->attack);
                player->HP -= monster->attack;
                printf("                你当前血量|%d|攻击力|%d| \n", player->HP, player->attack);
                printf("                你当前所在的位置是<%d , %d>\n ", player->x, player->y);
            }
            break;

        default:
            break;
        }
        printf("========================================end=============================================\n");

        if (player->HP <= 0)
        {
            printf("                你被│%s|击败了!\n", monster->name.string);
            player->HP = 0;
            return false;
        }
        if (monster->HP <= 0)
        {
            monster->HP = 0;
            printf("                你击败了|%s | !\n", monster->name.string);
            printf("                你当前血量|%d|攻击力|%d| \n", player->HP, player->attack);
            return true;
        }
    }
}

int Gain(struct Player *player, struct Treasure *treasure)
{

    printf("                    您遇了|%s|  增加攻击力:|%d|  增加血条:|%d|\n", treasure->name.string, treasure->ap, treasure->blood);
    printf("*********************************************************************************************\n");
    printf("*                                           发现宝藏                                         *\n");
    printf("*********************************************************************************************\n");
    while (player->HP > 0)
    {
        printf("                获得了一个宝贝\n");

        player->HP += treasure->blood;
        player->attack += treasure->ap;

        printf("                |%s|对你增加|%d|攻击力\n", treasure->name.string, treasure->ap);
        printf("                |%s|对你增加|%d|生命力\n", treasure->name.string, treasure->blood);
        treasure->blood -= treasure->blood;
        treasure->ap -= treasure->ap;
        printf("                你当前血量|%d|攻击力|%d| \n", player->HP, player->attack);
        printf("                你当前所在的位置是<%d , %d>\n ", player->x, player->y);
        break;
    }
    printf("========================================end=============================================\n");
}

int Money(struct Player *player, struct Coin *coin)
{
    printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$(^_^)$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
    while (player->HP > 0)
    {
        if (GetRandNumber(4) == 1)
        {
            printf("                天上掉馅饼,鸡哥赐宝|%d|坤\n", coin->value);
            printf("                您获得了|%s| 小金库增加|%d|坤\n", coin->name.string, coin->value);
            printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$(^_^)$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
            player->pocket += coin->value;
            coin->value -= coin->value;
            printf("你当前存有|%d|坤\n", player->pocket);
            break;
        }
        else if (GetRandNumber(4) == 2)
        {
            printf("                王涵涵送来了一个祝福，奖励|%d|坤\n", coin->value);
            printf("                您获得了|%s| 小金库增加|%d|坤\n", coin->name.string, coin->value);
            printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$(^_^)$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
            player->pocket += coin->value;
            coin->value -= coin->value;
            printf("                你当前存有|%d|坤\n", player->pocket);
            break;
        }
        else if (GetRandNumber(4) == 3)
        {
            printf("                你被打了个大逼兜，奖励|%d|坤\n", coin->value);
            printf("                您获得了|%s| 小金库增加|%d|坤\n", coin->name.string, coin->value);
            printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$(^_^)$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
            player->pocket += coin->value;
            coin->value -= coin->value;
            printf("                你当前存有|%d|坤\n", player->pocket);
            break;
        }
        else
        {
            printf("                遇到了外星人，奖励|%d|坤\n", coin->value);
            printf("                您获得了|%s| 小金库增加|%d|坤\n", coin->name.string, coin->value);
            printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$(^_^)$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
            player->pocket += coin->value;
            coin->value -= coin->value;
            printf("                你当前存有|%d|坤\n", player->pocket);
            break;
        }
    }
    printf("=======================================end==============================================\n");
}

void InitBoard(char (*p)[Map_Size])
{
    for (int i = 0; i < Map_Size; i++)
    {
        for (int j = 0; j < Map_Size; j++)
        {
            p[i][j] = '-';
        }
    }
}

void PrintMap(char (*p)[Map_Size], struct Player *player)
{
    InitBoard(p);

    p[player->y][player->x] = 'X';

    printf("    ");
    for (int i = 0; i < Map_Size; i++)
    {
        printf(" %5d", i + 1);
    }
    printf("\n");
    for (int i = 0; i < Map_Size; i++)
    {
        printf("%4d", i + 1);
        for (int j = 0; j < Map_Size; j++)
        {
            printf("  %4c", p[j][i]);
        }
        printf(" \n");
    }
}

int main()
{
    srand(time(NULL));
    system("clear");
    printf("*************************************************************************\n");
    printf("*   	                   欢迎来到魔塔世界！(^=^)!                     *\n");
    printf("*************************************************************************\n");

    char board[Map_Size][Map_Size];
    InitBoard(board);

    struct Player player;
    InitPlayer(&player);

    struct DynamicArray monsters = {NULL, 10, 0};
    InitMonsters(&monsters);

    struct DynamicArray treasures = {NULL, 10, 0};
    InitTreasure(&treasures);

    struct DynamicArray coins = {NULL, 12, 0};
    InitCoin(&coins);

    while (1)
    {
        // PrintMap(board, &player);
        printf("你当前所在的位置是<%d , %d>\n ", player.x + 1, player.y + 1);

        for (int i = 0; i < monsters.len; i++)
        {
            struct Monster *monster = (struct Monster *)monsters.dp[i];
            if (monster->HP > 0 && monster->x == player.x && monster->y == player.y)
            {
                if (Battle(&player, monster) == false)
                {
                    printf("Game over!\n");
                    break;
                }
            }
        }

        for (int i = 0; i < treasures.len; i++)
        {
            struct Treasure *treasure = (struct Treasure *)treasures.dp[i];
            if (treasure->ap > 0 && treasure->x == player.x && treasure->y == player.y)
            {
                if (Gain(&player, treasure) == true)
                {
                    printf("Gain over!\n");
                    break;
                }
            }
        }

        for (int i = 0; i < coins.len; i++)
        {
            struct Coin *coin = (struct Coin *)coins.dp[i];
            if (coin->value > 0 && coin->x == player.x && coin->y == player.y)
            {
                if (Money(&player, coin) == true)
                {
                    printf("Get Money\n");
                    break;
                }
            }
        }

        if (player.HP == 0)
            break;
        PrintMap(board, &player);
        printf("请选择你要进行的移动(输入'w ' , 'a' , 's ' ,'d '):");
        printf("\n");
        char choice;
        scanf("%c", &choice);
        int c;
        while ((c = getchar()) != '\n' && c != EOF)
        {
        }
        MakeMove(&player, choice);
    }

    for (int i = 0; i < treasures.len; i++)
    {
        struct Monster *monster = (struct Monster *)monsters.dp[i];
        free(monster->name.string);
        free(monster);
    }
    for (int i = 0; i < monsters.len; i++)
    {
        struct Treasure *treasure = (struct Treasure *)treasures.dp[i];
        free(treasure->name.string);
        free(treasure);
    }
    for (int i = 0; i < coins.len; i++)
    {
        struct Coin *coin = (struct Coin *)coins.dp[i];
        free(coin->name.string);
        free(coin);
    }

    free(monsters.dp);
    free(treasures.dp);
    free(coins.dp);
    return 0;
}
